package com.lxlg.lxlg_order.service.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lxlg.Lxlg_goods.client.GoodClient;
import com.lxlg.Lxlg_goods.client.result.FindGoodBySkuInfo;
import com.lxlg.core.utils.Result;
import com.lxlg.lxlg_massage.client.MassageClient;
import com.lxlg.lxlg_massage.client.param.SendMassageParam;
import com.lxlg.lxlg_order.alipay.config.AlipayConfig;
import com.lxlg.lxlg_order.client.param.OrderPayBackParam;
import com.lxlg.lxlg_order.client.param.SeckillOrderForm;
import com.lxlg.lxlg_order.client.result.SeckillOrderInfo;
import com.lxlg.lxlg_order.common.OrderException.OrderException;
import com.lxlg.lxlg_order.common.OrderException.OrderExceptionCode;
import com.lxlg.lxlg_order.common.constvalue.AllOrderConstValue;
import com.lxlg.lxlg_order.common.constvalue.RechargeConstValue;
import com.lxlg.lxlg_order.common.util.TokenUtil;
import com.lxlg.lxlg_order.infra.mapper.SeckillOrderMapper;
import com.lxlg.lxlg_order.infra.model.GoodsOrder;
import com.lxlg.lxlg_order.infra.model.OrderAndGoods;
import com.lxlg.lxlg_order.infra.model.SeckillOrder;
import com.lxlg.lxlg_order.service.service.SeckillOrderService;
import com.lxlg.user_server.client.UserClient;
import com.lxlg.user_server.client.param.UserIntegralChangeForm;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.connection.ReactiveSubscription;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kevin
 * @since 2022-04-28
 */
@Service
public class SeckillOrderServiceImpl extends ServiceImpl<SeckillOrderMapper, SeckillOrder> implements SeckillOrderService {
    @Resource
    private RedissonClient rc;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Resource
    private UserClient userClient;

    @Resource
    private GoodClient goodClient;

    @Resource
    private MassageClient massageClient;
    //生成订单
    @Override
    public Result<SeckillOrderInfo> addSeckillOrder(SeckillOrderForm seckillOrderForm) {
        //上锁
//        RLock lock = rc.getLock(seckillOrderForm.getSeckillId().toString());
//        lock.lock();

//        //rediss查询商品库存
//        阿勇
//        redisTemplate.opsForValue().get(seckillOrderForm.getSeckillId())
//
//        //判断库存是否够用
//
//        //redis减少库存


//        lock.unlock();
        //生成订单
        SeckillOrder seckillOrder = SeckillOrder.builder().build().setSeckillOrderCode("s" + UUID.randomUUID().toString().replace("-", ""))
                .setSeckillOrderState(AllOrderConstValue.order_payState_nopay)
                .setSeckillUserId(TokenUtil.getUserId())
                .setSeckillUserName(TokenUtil.getUserName())
                .setSkuId(seckillOrderForm.getSeckillId())
                .setSeckillPrice(seckillOrderForm.getSeckillPrice())
                .setCreateTime(new Date())
                .setSeckillGoodsNums(seckillOrderForm.getSeckillGoodsNums());

        save(seckillOrder);


//        private Integer seckillId;
//        @Min(0)
//        @ApiModelProperty("秒杀单价")
//        private String seckillPrice;
//        @Min(1)
//        @ApiModelProperty("秒杀商品数量")
//        private String seckillGoodsNums;


        //延时取消订单

        Message<String> message = MessageBuilder.withPayload(seckillOrder.getSeckillOrderCode()).build();
        rocketMQTemplate.asyncSend("seckillorder_cancle", message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("发送取消订单成功");
            }

            @Override
            public void onException(Throwable e) {
                System.out.println("发送取消订单失败");
            }
        }, RechargeConstValue.FormOrder_Cancle_delayTimeLevel);
        SeckillOrderInfo seckillOrderInfo = new SeckillOrderInfo();
        seckillOrderInfo.setSeckillOrderCode(seckillOrder.getSeckillOrderCode());
        return Result.getInstance(SeckillOrderInfo.class).setData(seckillOrderInfo);
    }
    //取消订单
    @Override
    public Result<String> cancleSeckillOrder(String message) {
        //查询订单
        QueryWrapper<SeckillOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("seckill_order_code",message);
        SeckillOrder seckillOrder = baseMapper.selectOne(queryWrapper);
        if (seckillOrder.getSeckillOrderState()!= AllOrderConstValue.order_payState_nopay) {
            throw new OrderException(OrderExceptionCode.ORDER_CANTCANCLE_EXCEPION);
        }
        //修改订单状态
        seckillOrder.setSeckillOrderState(AllOrderConstValue.order_payState_cancle);
        //释放库存
        Integer skuId = seckillOrder.getSkuId();

        return Result.getInstance(String.class).setData("取消订单成功");
    }
    //支付
    @Override
    public void doPaySeckillOrder(String seckillOrderCode, HttpServletResponse resp) throws IOException {
        QueryWrapper<SeckillOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("seckill_order_code",seckillOrderCode);
        SeckillOrder one = baseMapper.selectOne(queryWrapper);
        if(one==null){
            throw new OrderException(OrderExceptionCode.NOTEXSIT_ORDER_ERROR);
        }

        //================================================支付=======================================================================
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = one.getSeckillOrderCode();
        //付款金额，必填
        String total_amount = one.getSeckillPrice();
        //订单名称，必填
        String subject =TokenUtil.getUserName()+"的商品订单";
        //商品描述，可空
        String body ="商品购买";

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
//                + "\"order_type\":\""+ AllOrderConstValue.order_type_form +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");




        //若想给BizContent增加其他可选请求参数，以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //		+ "\"total_amount\":\""+ total_amount +"\","
        //		+ "\"subject\":\""+ subject +"\","
        //		+ "\"body\":\""+ body +"\","
        //		+ "\"timeout_express\":\"10m\","
        //		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

        //发送延时消息查看是否回调 ，redis中存储订单号设置状态为0表示没有支付回调
        OrderPayBackParam orderPayBackParam = new OrderPayBackParam();
        orderPayBackParam.setOrderCode(out_trade_no);
        orderPayBackParam.setOrderType(AllOrderConstValue.order_type_form);
        Message<OrderPayBackParam> message = MessageBuilder
                .withPayload(orderPayBackParam)//消息参数
//                .setHeader()//消息头
                .build();
        rocketMQTemplate.syncSend("Check_Order_pay",message,3000, RechargeConstValue.recharge_pay_delayTimeLevel);

        String result2=null;
        try {
            result2 = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        redisTemplate.opsForValue().set("order_pay:"+out_trade_no+"order_type"+AllOrderConstValue.order_type_form,"0",31, TimeUnit.MINUTES);
        //输出
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write(result2);


    }

    //支付回调
    @Override
    public void seckillorderPayBack(String orderCode) {
        //查询改订单
        QueryWrapper<SeckillOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("seckill_order_code",orderCode);
        SeckillOrder one = baseMapper.selectOne(queryWrapper);
        if(one==null){
            throw new OrderException(OrderExceptionCode.NOTEXSIT_ORDER_ERROR);
        }

        //删除redis中的订单
        redisTemplate.delete("order_pay:"+orderCode+"order_type"+AllOrderConstValue.order_type_form);

        //修改订单状态  已经支付
        one.setSeckillOrderState(AllOrderConstValue.order_payState_pay);
        saveOrUpdate(one);



        //用户减少积分

        //多个用户增加积分
        //用户减少积分
        UserIntegralChangeForm userIntegralChangeForm = new UserIntegralChangeForm();
        userIntegralChangeForm.setIntegralRecord(one.getConsumeAllScore());
        userIntegralChangeForm.setIntegralUpdateLog("积分减少");
        userClient.changeIntegralDeduction(userIntegralChangeForm);

        //多个用户增加积分
        UserIntegralChangeForm userIntegralChangeForm1 = new UserIntegralChangeForm();
        userIntegralChangeForm1.setIntegralRecord(Double.parseDouble(one.getGoodsPrice()));
        userIntegralChangeForm1.setIntegralUpdateLog("积分增加");
        userClient.changeUserIntegral(userIntegralChangeForm1);

        //获取订单中的商品  提醒商家发货
        Result<FindGoodBySkuInfo> goodBySku = goodClient.findGoodBySku(one.getSkuId());
        FindGoodBySkuInfo data = goodBySku.getData();
        one.setSeckillOrderState(AllOrderConstValue.order_goodsState_pay);
        //修改订单关联商品的状态
        //查询商品商家
        String merchantName = data.getMerchantName();
        SendMassageParam sendMassageParam = new SendMassageParam();
        sendMassageParam.setMsgAcceptName(merchantName);
        sendMassageParam.setMsgSendName(TokenUtil.getUserName());
        sendMassageParam.setMsgTypeId(2);
        sendMassageParam.setMsgContent("商品编号为："+one.getSkuId()+"的"+data.getGoodsName()+"商品需要发送"+one.getSeckillGoodsNums()+"件商品");
        massageClient.Sendmessage(sendMassageParam);


    }
}
